﻿using SelfMadeMillionaire.Core;
using SelfMadeMillionaire.Core.Services;
using System;
using System.Configuration;
using System.Web.Routing;
using System.Web;
using System.Web.Configuration;
using System.Web.Mvc;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Mail;
using System.Text;
using SelfMadeMillionaire.Core.Entities;
using SelfMadeMillionaire.Core.Repositories;

namespace SelfMadeMillionaire.BLL.Services
{
	public class EmailService : IEmailService
	{
        private readonly ILogRepository _logRepository;

        public EmailService(ILogRepository logRepository)
        {
            _logRepository = logRepository;
        }

		public bool SendAlerts(string emailTo, string subject, string body)
		{
			//return SendEmail(GetMailMessage(emailTo, subject, body), GetDefaultSmptClient());
            return SendAlerts(emailTo, subject, body, "");
		}

        public bool SendAlerts(string emailTo, string subject, string body, string emailFrom)
        {
            //return SendEmail(GetMailMessage(emailTo, subject, body, emailFrom), GetDefaultSmptClient());

            var msg = GetMailMessage(emailTo, subject, body, ConfigurationManager.AppSettings["ContactUsSmtpFrom"]);
            var client = GetContactUsSmptClient();
            return SendEmail(msg, client);
        }

        public void SendEmails(string emailTo, string subject, string body)
        {
            SendEmailWithEx(GetMailMessage(emailTo, subject, body), GetDefaultSmptClient());
        }

        public bool SendActivationEmail(Subscriber subscriber)
        {
            string emailBody = System.IO.File.ReadAllText(HttpContext.Current.Server.MapPath("~/EmailTemplates/Activation.html"));
            emailBody = emailBody
                .Replace("[verifyEmailAddress]",
                    GetUrlHelper().Action("Activate", "Account", new { token = subscriber.Token }, HttpContext.Current.Request.Url.Scheme))
                .Replace("[currentYear]", DateTime.Now.Year.ToString());

            return SendActivation(subscriber.Email, "Activation", emailBody);
        }

        public bool SendPasswordRecoveryEmail(Subscriber subscriber)
        {
            string emailBody = System.IO.File.ReadAllText(HttpContext.Current.Server.MapPath("~/EmailTemplates/ResetPassword.html"));
            emailBody = emailBody
                .Replace("[resetPasswordLink]",
                    GetUrlHelper().Action("ResetPassword", "Account", new { key = subscriber.PasswordRecoveryKey }, HttpContext.Current.Request.Url.Scheme));

            return SendPasswordRecovery(subscriber.Email, emailBody);
        }

        public bool SendPayPalConfirmEmail(Subscriber subscriber, string itemName, DateTime expDate)
        {
            string emailBody = System.IO.File.ReadAllText(HttpContext.Current.Server.MapPath("~/EmailTemplates/PayPalConfirm.html"));
            emailBody = emailBody
                .Replace("[fName]", subscriber.FirstName)
                .Replace("[lName]", subscriber.LastName)
                .Replace("[itemName]", itemName)
                .Replace("[expDate]", expDate.ToString("g"));

            return SendPayPalConfirm(subscriber.Email, emailBody);
        }

        public bool SendWelcomeLetter(Subscriber subscriber)
        {
            string emailBody = System.IO.File.ReadAllText(HttpContext.Current.Server.MapPath("~/EmailTemplates/WelcomeLetter.html"));
            emailBody = emailBody
                .Replace("[fName]", subscriber.FirstName)
                .Replace("[lName]", subscriber.LastName)
                .Replace("[link]", WebConfigurationManager.AppSettings["WebinarLink"]);

            return SendEmailFromSupport(subscriber.Email, "Welcome to Self-Made Millionaire Academy", emailBody);
        }

        public bool SendWebinarEmail(Subscriber subscriber)
        {
            string emailBody = System.IO.File.ReadAllText(HttpContext.Current.Server.MapPath("~/EmailTemplates/WebinarEmail.html"));
            emailBody = emailBody
                .Replace("[fName]", subscriber.FirstName)
                .Replace("[lName]", subscriber.LastName)
                .Replace("[link]", WebConfigurationManager.AppSettings["WebinarLink"]);

            return SendEmailFromSupport(subscriber.Email, "Confirmation of your webinar", emailBody);
        }
        
        static UrlHelper GetUrlHelper()
        {
            var httpContext = new HttpContextWrapper(HttpContext.Current);
            return new UrlHelper(new RequestContext(httpContext, CurrentRoute(httpContext)));
        }

        static RouteData CurrentRoute(HttpContextWrapper httpContext)
        {
            return RouteTable.Routes.GetRouteData(httpContext);
        }

        public bool SendEmailFromSupport(string emailTo, string subject, string body)
        {
            var msg = GetMailMessage(emailTo, subject, body, ConfigurationManager.AppSettings["supportEmail"]);

            var client = GetDefaultSmptClient();
            client.Credentials = new NetworkCredential(ConfigurationManager.AppSettings["supportEmail"], ConfigurationManager.AppSettings["supportEmailPassword"]);

            return SendEmail(msg, client);
        }

		public bool SendActivation(string emailTo, string subject, string body)
		{
			var msg = GetMailMessage(emailTo, subject, body, ConfigurationManager.AppSettings["activationEmail"]);

			var client = GetDefaultSmptClient();
            client.Credentials = new NetworkCredential(ConfigurationManager.AppSettings["activationEmail"], ConfigurationManager.AppSettings["activationEmailPassword"]);

			return SendEmail(msg, client);			
		}

        public bool SendPasswordRecovery(string emailTo, string body)
        {
            var msg = GetMailMessage(emailTo, "Choose a New Self-Made Millionaire Password", body, ConfigurationManager.AppSettings["PasswordResetSmtpFrom"]);
            var client = GetPasswordResetSmptClient();
            return SendEmail(msg, client);
        }

        public bool SendPayPalConfirm(string emailTo, string body)
        {
            var msg = GetMailMessage(emailTo, "Confirmation", body, ConfigurationManager.AppSettings["supportEmail"]);

            var client = GetDefaultSmptClient();
            client.Credentials = new NetworkCredential(ConfigurationManager.AppSettings["supportEmail"], ConfigurationManager.AppSettings["supportEmailPassword"]);

            return SendEmail(msg, client);
        }

		private void SendEmailWithEx(MailMessage msg, SmtpClient smtpClient)
		{
		    smtpClient.Send(msg);
		}

        private bool SendEmail(MailMessage msg, SmtpClient smtpClient)
        {
            try
            {
                SendEmailWithEx(msg, smtpClient);
                return true;
            }
            catch (Exception ex)
            {
                //new LoggingUtility().WriteErrorToLog(ex);
                try
                {
                    new LogService(_logRepository).Add(ex);
                }
                catch { }

                try
                {
                    SmtpClient reserveSmtp = GetReserveSmptClient();
                    msg.From = new MailAddress(ConfigurationManager.AppSettings["ReserveSmtpFrom"]);
                    reserveSmtp.Send(msg);
                    return true;
                }
                catch (Exception exSub)
                {
                    new LogService(_logRepository).Add(ex);
                }
            }

            return false;
        }

		private MailMessage GetMailMessage(string emailTo, string subject, string body, string emailFrom = null)
		{
            var msg = new MailMessage();
            msg.IsBodyHtml = true;
            msg.To.Add(emailTo);

            if (!string.IsNullOrWhiteSpace(emailFrom))
                msg.From = new MailAddress(emailFrom);

            msg.Body = body;
            msg.Subject = subject;

            return msg;
		}

		private SmtpClient GetDefaultSmptClient()
		{
			return new SmtpClient() { EnableSsl = false };
		}

        private SmtpClient GetReserveSmptClient()
        {
            SmtpClient result = new SmtpClient()
            { 
                Host = ConfigurationManager.AppSettings["ReserveSmtpHost"],
                Port = Convert.ToInt32(ConfigurationManager.AppSettings["ReserveSmtpPort"]),
                EnableSsl = Convert.ToBoolean(ConfigurationManager.AppSettings["ReserveSmtpEnableSSL"])
            };

            result.Credentials = new NetworkCredential(ConfigurationManager.AppSettings["ReserveSmtpUserName"], ConfigurationManager.AppSettings["ReserveSmtpPassword"]);
            return result;
        }

        private SmtpClient GetPasswordResetSmptClient()
        {
            SmtpClient result = new SmtpClient()
            {
                Host = ConfigurationManager.AppSettings["PasswordResetSmtpHost"],
                Port = Convert.ToInt32(ConfigurationManager.AppSettings["PasswordResetSmtpPort"]),
                EnableSsl = Convert.ToBoolean(ConfigurationManager.AppSettings["PasswordResetSmtpEnableSSL"])
            };

            result.Credentials = new NetworkCredential(ConfigurationManager.AppSettings["PasswordResetSmtpUserName"], ConfigurationManager.AppSettings["PasswordResetSmtpPassword"]);
            return result;
        }

        private SmtpClient GetContactUsSmptClient()
        {
            SmtpClient result = new SmtpClient()
            {
                Host = ConfigurationManager.AppSettings["ContactUsSmtpHost"],
                Port = Convert.ToInt32(ConfigurationManager.AppSettings["ContactUsSmtpPort"]),
                EnableSsl = Convert.ToBoolean(ConfigurationManager.AppSettings["ContactUsSmtpEnableSSL"])
            };

            result.Credentials = new NetworkCredential(ConfigurationManager.AppSettings["ContactUsSmtpUserName"], ConfigurationManager.AppSettings["ContactUsSmtpPassword"]);
            return result;
        }
	}
}
